// 定义三个常量表示状态
const PENDING = 'pending';
const FULFILLED = 'fulfilled';
const REJECTED = 'rejected';

// 新建 MyPromise 类
class MyPromise {
    constructor(executor) {
        // executor 是一个执行器，进入会立即执行
        // 并传入 resolve 和 reject 方法
        executor(this.resolve, this.reject);
    }

    // 储存状态的变量，初始值是 pending
    status = PENDING;

    // resolve 和 reject 为什么要用箭头函数
    // 如果直接调用的话，普通函数 this 会指向的是 window 或者 undefined
    // 用箭头函数就可以让 this 指向当前实例
    // 成功之后的值
    value = null;
    // 失败之后的原因
    reason = null;
    // 存储成功回调函数
    onFulfilledCallback = [];
    // onFulfilledCallback = null;
    // 存储失败回调函数
    onRejectedCallback = [];
    // onRejectedCallback = null;

    // 更改成功之后的状态
    resolve = (value) => {
        if (this.status === PENDING) {
            // 状态修改为成功
            this.status = FULFILLED;
            // 保存成功之后的值
            this.value = value;
            // 判断成功回调是否存在，存在就调用
            // 相当于
            // if (this.onFulfilledCallback) {
            //     this.onFulfilledCallback();
            // }
            // 利用了 && 的短路特性
            // this.onFulfilledCallback && this.onFulfilledCallback(value);
            while(this.onFulfilledCallback.length) {
                // Array.shift() 取出第一个元素，然后调用，传入参数，直到数组为空
                this.onFulfilledCallback.shift()(value);
            }
        }
    }

    // 更改失败之后的状态
    reject = (reason) => {
        if (this.status === PENDING) {
            // 状态改为失败
            this.status = REJECTED;
            // 保存失败之后的原因
            this.reason = reason;
            // 判断失败回调是否存在，存在则调用
            // this.onRejectedCallback && this.onRejectedCallback(reason);
            while(this.onRejectedCallback.length) {
                this.onRejectedCallback.shift()(reason);
            }
        }
    }

    then(onFulfilled, onRejected) {
        // 判断状态
        // 为了链式调用这里直接创建一个 MyPromise，并在后面 return 出去
        const promise2 = new MyPromise((resolve, reject) => {
            if(this.status === FULFILLED) {
                // 调用成功回调，并且把值返回
                const x = onFulfilled(this.value);
                // 传入 resolvePromise 集中处理
                resolvePromise(x, resolve, reject);
            } else if (this.status === REJECTED) {
                // 调用失败回调，并且把原因返回
                onRejected(this.reason);
            } else if (this.status === PENDING) {
                // 因为还不知道结果，所以先将回调函数暂存
                // 结果出现时再将参数传入回调中调用
                // this.onFulfilledCallback = onFulfilled;
                // this.onRejectedCallback = onRejected;
                this.onFulfilledCallback.push(onFulfilled);
                this.onRejectedCallback.push(onRejected);
            }
        });

        return promise2;
    }
}

function resolvePromise(x, resolve, reject) {
    if(x instanceof MyPromise) {
        // 执行 x，调用 then 方法，目的是将其状态变为 fulfilled 或者 rejected
        // x.then(value => resolve(value), reason => reject(reason))
        // 简化之后
        x.then(resolve, reject);
    } else {
        // 普通值
        resolve();
    }
}

export default MyPromise;
// module.exports = MyPromise;